﻿using FittyWars.MathUtil;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FittyWars.BordUtils
{
    public class Element
    {
        public enum ElementType
        {
            Moving,
            Still
        }

        public Vector Center
        {
            get
            {
                return m_center;
            }
            set
            {
                m_center = value;
                m_validGeometrics = false;
            }
        }
        public float Angle  // in degrees, 0 is right
        {
            get
            {
                return m_angle;
            }
            set
            {
                m_angle = value;
                m_validGeometrics = false;
            }
        }
        public float Radious { get; protected set; }
        public ElementType EleType { get; protected set; }
        public List<Polygon> BodyParts
        {
            get
            {
                return m_bodyParts;
            }
            protected set
            {
                Radious = (value != null && value.Any())
                    ? value.Max(p => p.Vectors.Max(v => v.Size()))
                    : 0.0f;
                m_bodyParts = value;
            }
        }
        public GameElement GameElement { get; protected set; }


        private Vector m_center;
        private float m_angle;
        private bool m_validGeometrics;
        public List<Polygon> m_bodyParts;
        private List<Polygon> m_CurrentGeometrics;
        private List<Polygon> m_FutureGeometrics;
        private Vector m_futureCenter;
        private Polygon pframe;

        public Element()
        {
            Center = new Vector(0,0);
            Radious = 0;
            Angle = 0;
            EleType = ElementType.Still;
            BodyParts = null;
            GameElement = GameElement.None;
            m_CurrentGeometrics = null;
            m_FutureGeometrics = null;
            m_validGeometrics = false;
        }

        public Element(List<Polygon> bodyparts) : this()
        {
            this.BodyParts = bodyparts;
        }

        public List<Polygon> GetElementGeometrics()
        {
            if (m_validGeometrics)
            {
                return m_CurrentGeometrics;
            }
            Matrix mat = new Matrix();
            mat.Translate(
                Center.X,
                Center.Y
                );
            mat.Rotate(Angle);
            m_CurrentGeometrics = BodyParts.Select(p => new Polygon(p.Vectors.Select(v => v.ApplyMatrix(mat)).ToList())).ToList();
            m_validGeometrics = true;
            return m_CurrentGeometrics;
        }

        public void SetFutureCenterGeometrics(float newx, float newy, float dt)
        {
            Matrix mat = new Matrix();
            mat.Translate(newx, newy );
            mat.Rotate(Angle + dt);
            m_FutureGeometrics = BodyParts.Select(p => new Polygon(p.Vectors.Select(v => v.ApplyMatrix(mat)).ToList())).ToList();
            m_futureCenter = new Vector(newx, newy);
        }

        public List<Polygon> GetElementFutureGeometrics()
        {
            return m_FutureGeometrics;
        }

        public Vector GetFutureCenter()
        {
            return m_futureCenter;
        }

        public void UpdateToFutureGeometrics()
        {
            m_CurrentGeometrics = m_FutureGeometrics.ToList();
            m_center = m_futureCenter;
            m_validGeometrics = true;
        }
    }
}
